package en.kaist.cs408.acav;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.HashMap;

import en.kaist.cs408.acav.CreateClass.NetworkHandler;
import android.os.Message;
import android.util.Log;

public class NetworkThread extends Thread {
	private int request;
	private String courseID;
	private String studentID;
	private String pwdEncrypt;
	private String hotspotAddress;
	private String voiceFileName;
	private String date;
	private MyAdapter listAdapter;
	private boolean attBool;
	
	private NetworkHandler handler;
	
	Message msg;

	/* request = 3000 (in CreateClass.java)
	 * input: courseID, password / output: state(create a class in course table)
	 */
	/*
	public NetworkThread(int request, String courseID, String pwdEncrypt,
			NetworkHandler handler) {
		this.request = request;
		this.courseID = courseID;
		this.pwdEncrypt = pwdEncrypt;

		this.handler = handler;
	}
*/
	/* request = 2000 (in StartCheck.java)
	 * input: courseID, password, hotspotAddress / output: state(start checking procedure)
	 */
	/*
	public NetworkThread(int request, String courseID, String pwdEncrypt,
			String hotspotAddress, NetworkHandler handler) {
		this.request = request;
		this.courseID = courseID;
		this.pwdEncrypt = pwdEncrypt;
		this.hotspotAddress = hotspotAddress;

		this.handler = handler;
	}
*/
	/* request = 1000 (in CheckVoice.java)
	 * input: courseID / output: hotspotAddress and state
	 */
	/*
	public NetworkThread(int request, String courseID, NetworkHandler handler){
		this.request = request;
		this.courseID = courseID;
		this.handler = handler;
	}
	*/
	public NetworkThread(int request, String courseID, String studentID, 
			String pwdEncrypt, String hotspotAddress, String voiceFileName, 
			String date, MyAdapter listAdapter, boolean attBool, NetworkHandler handler){
		switch(request){
			case 0:
			{
				this.request = request;
				this.handler = handler;
				break;
			}
			case 1000:
			{
				this.request = request;
				this.courseID = courseID;
				this.handler = handler;
				break;
			}
			case 1100:
			{
				this.request = request;
				this.courseID = courseID;
				this.studentID = studentID;
				this.voiceFileName = voiceFileName;
			}
			case 1200:
			{
				this.request = request;
				this.voiceFileName = voiceFileName;
			}
			case 1300:
			{
				this.request = request;
				this.courseID = courseID;
				this.studentID = studentID;
				this.voiceFileName = voiceFileName;
				this.handler = handler;
				break;
			}
			case 2000:
			{
				this.request = request;
				this.courseID = courseID;
				this.pwdEncrypt = pwdEncrypt;
				this.hotspotAddress = hotspotAddress;
				this.handler = handler;
				break;
			}
			case 2100:
			{
				this.request = request;
				this.courseID = courseID;
				this.handler = handler;
				break;
			}
			case 3000:
			{
				this.request = request;
				this.courseID = courseID;
				this.pwdEncrypt = pwdEncrypt;
				this.handler = handler;
				break;
			}
			case 4000:
			{
				this.request = request;
				this.courseID = courseID;
				this.pwdEncrypt = pwdEncrypt;
				this.date = date;
				this.listAdapter = listAdapter;
				this.handler = handler;
			}
			case 5000:
			{
				this.request = request;
				this.courseID = courseID;
				this.studentID = studentID;
				this.date = date;
				this.attBool = attBool;
				this.handler = handler;
			}
			default:
			{
				Log.d("Chwang", "Not Defined Operation: " + request);
			}
		}
	}
	
	@Override
	public void run() {
		Socket sc = null;

		try {
			msg = handler.obtainMessage();

			sc = new Socket("cs408.kaist.ac.kr", 3080);

			InputStream is = sc.getInputStream();
			OutputStream os = sc.getOutputStream();

			DataInputStream dis = new DataInputStream(is);
			DataOutputStream dos = new DataOutputStream(os);

			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));

			if (request == 0){
				dos.writeInt(0);
				msg.what = 0;
				
				handler.sendMessage(msg);
				
			} else if (request == 1000){
				dos.writeInt(1000);
				
				bw.write(courseID+"\n");
				bw.flush();
				
				int status = dis.readInt();
				//msg.what = status;
				
				String hotspotAddress = br.readLine();
				
				if (status == 0){
					msg.what = 0;
					msg.obj = hotspotAddress;
					handler.sendMessage(msg);
				} else if (status == -1){
					// the courseID does NOT exist
					msg.what = -1;
					msg.obj = hotspotAddress;
					handler.sendMessage(msg);
				} else if (status == -2){
					msg.what = -2;
					msg.obj = hotspotAddress;
					handler.sendMessage(msg);
				} else {
					// SQLException occurred
					msg.what = -3;
					msg.obj = hotspotAddress;
					handler.sendMessage(msg);
				}
				
			} else if (request == 1100) {
				dos.writeInt(1100);
				dos.flush();
				
				bw.write(courseID+"\n");
				bw.flush();
				
				bw.write(studentID+"\n");
				bw.flush();
				
				Log.d("Chwang", voiceFileName);
				
				
				int state = dis.readInt();
				
				
				if (state == 0){
					// There exists the record of the course ID and the student ID
					msg.what = 0;
					handler.sendMessage(msg);
				} else if (state == -1){
					// No such course ID
					msg.what = -1;
					handler.sendMessage(msg);
				} else if (state == -2){
					// No such student ID in the course
					msg.what = -2;
					handler.sendMessage(msg);
				} else if (state == -100){
					// SQLException Occurred
					msg.what = -100;
					handler.sendMessage(msg);
				}
			} else if (request == 1200){
				/*
				dos.writeInt(1200);
				WavFileSender fs = new WavFileSender(sc);
				fs.start();
				Thread.sleep(5000);*/
			} else if (request == 1300){
				dos.writeInt(1300);
				
				bw.write(courseID+"\n");
				bw.flush();
				
				bw.write(studentID+"\n");
				bw.flush();
				
				
				int state = dis.readInt();
				
				if (state == 0){
					msg.what = 0;
					handler.sendMessage(msg);
				} else {
					msg.what = state;
					handler.sendMessage(msg);
				}
			}
			else if (request == 2000){
				dos.writeInt(2000);
				
				bw.write(courseID + "\n");
				bw.flush();
				
				bw.write(pwdEncrypt + "\n");
				bw.flush();
				
				bw.write(hotspotAddress + "\n");
				bw.flush();
				
				int status = dis.readInt();
				
				if (status == 0) {
					// authorization OK
					// send mac address and start checking
					msg.what = 0;
					handler.sendMessage(msg);
				} else if (status == -1) {
					// authorization fail
					msg.what = -1;
					handler.sendMessage(msg);
				} else if (status == -2) {
					// Another problem
					msg.what = -2;
					handler.sendMessage(msg);
				} else {
					msg.what = status;
					handler.sendMessage(msg);
				}
				
			} else if (request == 2100) {
				/* Stop Attendance Checking */
				dos.writeInt(2100);
				
				bw.write(courseID + "\n");
				bw.flush();
				
				int status = dis.readInt();
				
				if (status == 0){
					msg.what = 0;
					handler.sendMessage(msg);
				} else {
					msg.what = status;
					handler.sendMessage(msg);
				}
			} else if (request == 3000) {
				dos.writeInt(3000);

				bw.write(courseID + "\n");
				bw.flush();

				bw.write(pwdEncrypt + "\n");
				bw.flush();

				int status = dis.readInt();
				
				Log.d("Chwang", Integer.toString(status));

				if (status == 0) {
					msg.what = 0;
					handler.sendMessage(msg);
					// Activity change to success page
				} else if (status == -1) {
					msg.what = -1;
					handler.sendMessage(msg);
				} else {
					msg.what = -2;
					handler.sendMessage(msg);
				}
			} else if (request == 4000) {
				dos.writeInt(4000);
				
				bw.write(courseID + "\n");
				bw.flush();
				
				bw.write(pwdEncrypt + "\n");
				bw.flush();
				
				bw.write(date + "\n");
				bw.flush();
				
				int status = dis.readInt();
				
				if (status == 0){
					int numStudent = dis.readInt();
					
					for(int i=0; i<numStudent; i++){
						String sid = dis.readUTF();
						boolean att_bool = dis.readBoolean();
						
						Student newStudent = new Student(sid, att_bool);
						listAdapter.add(newStudent);
					}
					
					msg.what = 0;
					handler.sendMessage(msg);
				} else if (status == -1){
					msg.what = -1;
					handler.sendMessage(msg);
				} else {
					msg.what = -100;
					handler.sendMessage(msg);
				}
				

			} else if (request == 5000) {
				/* manually checking */
				dos.writeInt(5000);
				
				bw.write(courseID+"\n");
				bw.flush();
				
				bw.write(studentID+"\n");
				bw.flush();
				
				bw.write(date+"\n");
				bw.flush();
				
				if (attBool == true){
					bw.write("true\n");
					bw.flush();
				}
				else{
					bw.write("false\n");
					bw.flush();
				}
				
				
				int state = dis.readInt();
				
				msg.what = state;
				handler.sendMessage(msg);
			}

		} catch (UnknownHostException e) {
			Log.d("Chwang", e.toString());
			msg.what = -3;
			handler.sendMessage(msg);
		} catch (IOException e) {
			Log.d("Chwang", e.toString());
			msg.what = -4;
			handler.sendMessage(msg);
		} catch (Exception e) {
			Log.d("Chwang", e.toString());
			msg.what = -5;
			handler.sendMessage(msg);
		} finally {
			/*
			if (sc != null)
				try {
					sc.close();
				} catch (IOException e) {
					Log.d("Chwang", "Exception in Socket closing");
					e.printStackTrace();
				}*/
		}
	}
}
